package me.weijing.common.http;

import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ExecutorService;

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.text.TextUtils;
import android.util.Log;

/**
 * 请求http的基类
 * 
 * @author jiayuan.luo 2013-8-16下午2:30:07
 * @version 1.0.0
 * @category 杭州尤拉夫科技有限公司(微警)
 */
public abstract class AsyncHttpRequestBase {
    private static final String TAG = "AsyncHttpRequestBase";

    public static enum EFailType {
        EFAILTYPE_SYS(0), EFAILTYPE_APP(1);
        int val;

        EFailType(int v) {
            this.val = v;
        }
    };

    public final static int FAILTYPE_CLIENT_REQPARAM = -100;
    public final static int FAILTYPE_CLIENT_CREATETHREAD = -101;
    public final static int FAILTYPE_NETFAIL = -150;
    public final static int FAILTYPE_DISKFAIL = -151;
    public final static int FAILTYPE_SERVER_FAIL = -180;

    private static String gSessionValidTag = null;
    private String sessionTag = null;

    protected static ExecutorService mThreadPool = java.util.concurrent.Executors.newCachedThreadPool();

    protected Context mContext;
    protected Handler mHandler = null;
    protected HttpProgressCallback mCallback = null;
    public static Map<String, String> gExtraHeader;

    public static void setGlobalSessionValidTag(String tag) {
        gSessionValidTag = tag;
    }

    public static String getGlobalSessionValidTag() {
        return gSessionValidTag;
    }

    public static void setExtraHeader(Map<String, String> extraHeader) {
        gExtraHeader = extraHeader;
    }

    AsyncHttpRequestBase(Context context) {
        this.mContext = context;
        if (mContext != null) {
            mHandler = new Handler(mContext.getMainLooper());
        } else {
            mHandler = new Handler(Looper.getMainLooper());
        }
    }

    public String getSessionTag() {
        return sessionTag;
    }

    public void setSessionTag(String tag) {
        sessionTag = tag;
    }

    public boolean checkSessionTag() {
        if (TextUtils.isEmpty(getSessionTag()))
            return true;
        if (getGlobalSessionValidTag() == null)
            return false;
        if (getGlobalSessionValidTag().equals(getSessionTag()))
            return true;
        return false;
    }

    public void cancel() {
        setSessionTag(UUID.randomUUID().toString());
        try {
            processCanceled();
        } catch (Exception e) {
            e.printStackTrace();
        } catch (Throwable t) {
            t.printStackTrace();
        }
        try {
            processFinish();
        } catch (Exception e) {
            e.printStackTrace();
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }

    protected String buildUrl(RequestParams reqParam) throws Exception {

        String url = getUrl();
        if (url == null) {
            throw new Exception("not sepcified url");
        }
        url = url.trim();
        StringBuffer realUrl = new StringBuffer(url);
        if (-1 == url.indexOf('?')) {
            realUrl.append("?");
        } else {
            if (url.endsWith("&") == false)
                realUrl.append("&");
        }

        Map<String, String> extraUrlParam = getExtraUrlParam();
        if (null == extraUrlParam) {
            if (null != reqParam)
                realUrl.append(reqParam.toString());
            return realUrl.toString();
        }
        RequestParams extraUrlParam2 = new RequestParams(extraUrlParam);
        realUrl.append(extraUrlParam2.toString());
        if (null != reqParam) {
            realUrl.append("&");
            realUrl.append(reqParam.toString());
        }
        return realUrl.toString();
    }

    // setRequestProperty
    public Map<String, String> getExtraHeader() {
        return null;
    }

    public Map<String, String> getExtraUrlParam() {
        return null;
    }

    public abstract String getUrl();

    /*
     * <p> 该函数是在UI线程里执行，是异常安全的，即使应用不处理异常，程序也不会Crash </p>
     */

    public void processFailed(EFailType failtype, int resultCode, String errMsg) {
        String msg = "resultCode=" + resultCode;
        msg += ",errMsg=" + errMsg;
        Log.i(TAG, msg);

    }

    public abstract void launchProgress();

    public abstract void processCanceled();

    public abstract void publishProgress(int progress);

    public abstract void processFinish();
}
